<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport"
        content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no">
    <title>可视域分析_3DTiles</title>
    <link href="../Build/Cesium/Widgets/widgets.css" rel="stylesheet" />
    <script src="../Build/Cesium/Cesium.js"></script>
    <script src="plugin/MathTools.js"></script>
    <script src="plugin/PrimitivePoints.js"></script>
    <script src="plugin/EllipseGeometryLibraryEx_.js"></script>
    <script src="plugin/3DTilesToolCopy.js"></script>
    <style>
        html,
        body,
        #cesiumContainer {
            width: 100%;
            height: 100%;
            margin: 0;
            padding: 0;
            overflow: hidden;
        }
    </style>

</head>

<body>
    <div id="cesiumContainer"></div>
    <script>
        let mapbox = new Cesium.MapboxImageryProvider({
            mapId: 'mapbox.dark',
            accessToken: 'pk.eyJ1IjoieW91bmdnaXMiLCJhIjoiY2o5Z3owdTViMnR5djJ3bGczaGw4ODdhZSJ9.K7Zmkra18V7CuynSW3rlRQ'
        });

        let viewer = new Cesium.Viewer('cesiumContainer', {
            imageryProvider: mapbox,
            contextOptions: {
                webgl: {
                    alpha: true
                }
            },
            selectionIndicator: false,
            animation: false, //是否显示动画控件
            baseLayerPicker: false, //是否显示图层选择控件
            geocoder: false, //是否显示地名查找控件
            timeline: false, //是否显示时间线控件
            sceneModePicker: false, //是否显示投影方式控件
            navigationHelpButton: false, //是否显示帮助信息控件
            infoBox: false, //是否显示点击要素之后显示的信息
            fullscreenButton: false,
            shouldAnimate: true //动画播放
        });

        //取消双击事件
        //viewer.cesiumWidget.screenSpaceEventHandler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK);
        //设置homebutton的位置
        Cesium.Camera.DEFAULT_VIEW_RECTANGLE =
            Cesium.Rectangle.fromDegrees(116.15, 40.54, 116.25, 40.56); //Rectangle(west, south, east, north)
        //设置初始位置
        viewer.camera.setView({
            destination: Cesium.Cartesian3.fromDegrees(116.20, 40.55, 3000000)
        });

        //开启深度检测
        //viewer.scene.globe.depthTestAgainstTerrain = true;

        let tileset = viewer.scene.primitives.add(new Cesium.Cesium3DTileset({
            url: '../Source/3DTiles/building_1/tileset.json' // '../Source/3DTiles/building/tileset.json'
        }));

        tileset.readyPromise.then(function (tileset) {
            viewer.scene.primitives.add(tileset);
            viewer.zoomTo(tileset, new Cesium.HeadingPitchRange(0.5, -0.2, tileset.boundingSphere.radius * 1.0));

            setTimeout(function () {
                DrawLineKSY()
            }, 5000)
        }).otherwise(function (error) {
            console.log(error);
        });


        viewer.scene.fxaa = false;
        viewer.scene.fog.enabled = false;
        viewer.scene.globe.depthTestAgainstTerrain = true;

        //可视域
        var primitiveKSY = [];
        function DrawLineKSY() {
            if (primitiveKSY.length > 0) { return; }
            var viewHeight = 1.5;
            var cartographicCenter = Cesium.Cartographic.fromDegrees(104.07, 30.64);
            var cartesianCenterH0 = Cesium.Cartesian3.fromRadians(cartographicCenter.longitude, cartographicCenter.latitude);
            var cartesianPointH0 = Cesium.Cartesian3.fromDegrees(104.071, 30.641);
            var ab = Cesium.Cartesian3.distance(cartesianCenterH0, cartesianPointH0);
            var eopt = {};
            eopt.semiMinorAxis = ab;
            eopt.semiMajorAxis = ab;
            eopt.rotation = 0;
            eopt.center = cartesianCenterH0;
            eopt.granularity = Math.PI / 45.0;//间隔
            var ellipse = EllipseGeometryLibraryEx.computeEllipseEdgePositions(eopt);
   
            for (var i = 0; i < ellipse.outerPositions.length; i += 3) {
                //逐条计算可视域
                var cartesian = new Cesium.Cartesian3(ellipse.outerPositions[i], ellipse.outerPositions[i + 1], ellipse.outerPositions[i + 2]);
                var cartographic = Cesium.Cartographic.fromCartesian(cartesian);
                var deltaRadian = 0.00005 * Math.PI / 180.0; //Cesium.Math.RADIANS_PER_DEGREE
                var cartographicArr = SysMathTool.InterpolateLineCartographic(cartographicCenter, cartographic, deltaRadian);
                
                ThreeDTilesToolCopy.CartographicPointsTerrainData(viewer.scene, cartographicArr,
                    function (terrainData) {
                        if (terrainData.length > 0) {
                            var preVisible = true;
                            var cartesiansLine = [];
                            var colors = [];
                            for (var j = 1; j < terrainData.length; j++) {
                                //逐点计算可见性
                                var visible = true;//该点可见性
                                if (j > 1) {
                                    var cartographicCenterHV = new Cesium.Cartographic(terrainData[0].longitude, terrainData[0].latitude, terrainData[0].height + viewHeight);
                                    //
                                    if (preVisible) {
                                        //     
                                        var curPoint = SysMathTool.InterpolateIndexLineHeightCartographic(cartographicCenterHV, terrainData[j], j, j - 1);
                                        if (curPoint.height >= terrainData[j - 1].height) {
                                            preVisible = true;
                                            visible = true;
                                        } else {
                                            preVisible = false;
                                            visible = false;
                                        }
                                    } else {
                                        //插值到当前
                                        var curPointArr = SysMathTool.Interpolate2IndexLineHeightCartographic(cartographicCenterHV, terrainData[j], j, j - 1);
                                        for (var k = 0; k < curPointArr.length; k++) {
                                            if (curPointArr[k].height >= terrainData[k].height) {
                                                preVisible = true;
                                                visible = true;
                                            } else {
                                                preVisible = false;
                                                visible = false;
                                                break;
                                            }
                                        }
                                    }
                                }
                                var cartesianTemp = Cesium.Cartesian3.fromRadians(terrainData[j].longitude, terrainData[j].latitude, terrainData[j].height + 1);
                                cartesiansLine.push(cartesianTemp);
                                //绘制点
                                if (visible) {
                                    colors.push(0);
                                    colors.push(0);
                                    colors.push(1);
                                    colors.push(1);
                                } else {
                                    colors.push(1);
                                    colors.push(0);
                                    colors.push(0);
                                    colors.push(1);
                                }
                            }

                            //绘制结果
                            var pointsKSY = new PrimitivePoints({ 'viewer': viewer, 'Cartesians': cartesiansLine, 'Colors': colors });
                            primitiveKSY.push(pointsKSY);
                        } else {
                            alert("高程异常！");
                        }
                    });
            }

        }


    </script>
</body>

</html>